package org.jeecg.modules.manager.service.impl;

import com.alipay.api.domain.Sale;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.manager.entity.*;
import org.jeecg.modules.manager.mapper.*;
import org.jeecg.modules.manager.service.ISaleOrderService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.mapper.SysUserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 销售订单表
 * @Author: jeecg-boot
 * @Date: 2021-11-19
 * @Version: V1.0
 */
@Service
public class SaleOrderServiceImpl extends ServiceImpl<SaleOrderMapper, SaleOrder> implements ISaleOrderService {

    @Autowired
    private SaleOrderMapper saleOrderMapper;

    @Autowired
    private OrderGroupMapper orderGroupMapper;

    @Autowired
    private GoodsTypeMapper goodsTypeMapper;

    @Autowired
    private CarMapper carMapper;

    @Autowired
    private RepositoryMapper repositoryMapper;

    @Autowired
    private PurchaseOrderMapper purchaseOrderMapper;

    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private CarInfoMapper carInfoMapper;

    @Autowired
    private SparePartsMapper sparePartsMapper;

    @Autowired
    private SupplierMapper supplierMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisUtil redisUtil;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrEdit(OrderGroupSaleVo orderGroup, LoginUser loginUser) {
        try {
            OrderGroup real = new OrderGroup();
            BeanUtils.copyProperties(orderGroup,real);
            //有id则修改
            if (StringUtils.isNotBlank(orderGroup.getId())) {
                //拼个名字吧。。。
                orderGroup.getSaleOrderAddVoList().forEach(vo -> {
                    SaleOrder saleOrder = new SaleOrder();
                    BeanUtils.copyProperties(vo,saleOrder);
                    extracted(vo, saleOrder);
                    saleOrder.setUpdatedBy(loginUser.getUsername());
                    saleOrder.setUpdatedTime(new Date());
                    saleOrderMapper.updateById(saleOrder);
                });
                spellName(orderGroup, loginUser);
                orderGroupMapper.updateById(real);
            } else {
                real.setId(UUIDGenerator.generate());
                //拼个名字吧。。。
                spellName(orderGroup, loginUser);
                real.setOrderType(OrderType.SALE);
                real.setCreatedTime(new Date());
                real.setCreatedBy(loginUser.getUsername());
                real.setDeleted(DeletedEnum.FALSE);
                orderGroupMapper.insert(real);
                orderGroup.getSaleOrderAddVoList().forEach(vo -> {
                    SaleOrder saleOrder = new SaleOrder();
                    BeanUtils.copyProperties(vo,saleOrder);
                    vo.setSaleOrderId(UUIDGenerator.generate());
                    vo.setOrderGroupId(orderGroup.getId());
                    vo.setSaleOrderNumber(UUIDGenerator.generate());
                    extracted(vo, saleOrder);
                    saleOrder.setSaleOrderStatus(0);
                    saleOrder.setDeleted(DeletedEnum.FALSE);
                    saleOrder.setCreatedBy(loginUser.getUsername());
                    saleOrder.setCreatedTime(new Date());
                    saleOrderMapper.insert(saleOrder);
                });
            }
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    private void extracted(SaleOrderAddVo vo, SaleOrder saleOrder) {
        //查找商品价格计算总价和单价
        CarInfo carInfo = carInfoMapper.selectById(vo.getSaleOrderGoodsId());
        if (Objects.nonNull(carInfo)){
            saleOrder.setSaleOrderPrice(new BigDecimal(carInfo.getInfoPrice()));
        }else {
            SpareParts spareParts = sparePartsMapper.selectById(vo.getSaleOrderGoodsId());
            saleOrder.setSaleOrderPrice(new BigDecimal(spareParts.getSparePartsPrice()));
        }
        //算一下总价
        saleOrder.setSaleOrderTotal(saleOrder.getSaleOrderPrice().multiply(new BigDecimal(vo.getSaleOrderCount())));
        //寻找一个仓库
        Map<String, Stock> stockMap = stockMapper.selectList(new QueryWrapper<Stock>()
                .eq("stock_goods_id", vo.getSaleOrderGoodsId())
        ).stream().collect(Collectors.toMap(Stock::getId, java.util.function.Function.identity()));
        stockMap.forEach((id,stock)->{
            boolean hasKey = redisUtil.hasKey(id);
            if (stock.getStockCount() > vo.getSaleOrderCount()){
                saleOrder.setSaleOrderRepoId(stock.getStockRepoId());
                if (!hasKey){
                    redisUtil.set(id,vo.getSaleOrderCount());
                }else{
                    redisUtil.incr(id,vo.getSaleOrderCount());
                }
                //暂时扣库存
                stockMapper.updateById(new Stock().setId(id).setStockCount(stock.getStockCount() - saleOrder.getSaleOrderCount()));
            } else {
                throw new RuntimeException("库存不足！");
            }
        });
    }


    @Override
    public List<SaleQueryByIdVo> queryById(String id) {

        List<SaleOrder> orderList = saleOrderMapper.selectList(new QueryWrapper<SaleOrder>().eq("order_group_id", id).eq("deleted", DeletedEnum.FALSE));

        return orderList.stream().map(order -> {
            SaleQueryByIdVo vo = SaleQueryByIdVo.makeVo(order);
            AtomicBoolean flag = new AtomicBoolean(false);
            //名字
            Optional.ofNullable(carInfoMapper.selectById(vo.getSaleOrderGoodsId())).ifPresent(carInfo -> {
                vo.setSaleOrderGoodsName(carInfo.getInfoManufacturer()+carInfo.getInfoVersion()+carInfo.getInfoColor());
                flag.set(true);
            });
            if (!flag.get()){
                vo.setSaleOrderGoodsName(sparePartsMapper.selectById(vo.getSaleOrderGoodsId()).getSparePartsName());
            }
            //客户
            Optional.ofNullable(sysUserMapper.selectById(vo.getSaleOrderUserId())).ifPresent(user->{
                vo.setSaleOrderUserRealName(user.getRealname());
            });
            //仓库
            Optional.ofNullable(repositoryMapper.selectById(vo.getSaleOrderRepoId())).ifPresent(repository->{
                vo.setSaleOrderRepoName(repository.getRepoName());
            });
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeAllById(String id,LoginUser cur) {
        try {
            orderGroupMapper.updateById(new OrderGroup().setId(id).setDeleted(DeletedEnum.TRUE));
            Optional.ofNullable(saleOrderMapper.selectList(new QueryWrapper<SaleOrder>().eq("order_group_id",id))).ifPresent(
                    saleOrders -> saleOrders.forEach(saleOrder -> {
                        saleOrder.setUpdatedTime(new Date());
                        saleOrder.setUpdatedBy(cur.getUsername());
                        saleOrder.setDeleted(DeletedEnum.TRUE);
                        saleOrder.setSaleOrderStatus(2);
                        redisUtil.decr(saleOrder.getSaleOrderGoodsId()+","+saleOrder.getSaleOrderRepoId(),saleOrder.getSaleOrderCount());
                        Stock stock = stockMapper.selectById(saleOrder.getSaleOrderGoodsId() + "," + saleOrder.getSaleOrderRepoId());
                        stockMapper.updateById(stock.setStockCount(stock.getStockCount()+saleOrder.getSaleOrderCount()));
                        saleOrderMapper.updateById(saleOrder);
                    }));
            return 0;
        }catch (Exception e){
            return -1;
        }
    }

    @Override
    @Transactional
    public String removeOrderById(String id, LoginUser cur) {
        SaleOrder saleOrder = saleOrderMapper.selectById(id);
        if (saleOrder != null){
            redisUtil.decr(saleOrder.getSaleOrderGoodsId()+","+saleOrder.getSaleOrderRepoId(),saleOrder.getSaleOrderCount());
            Stock stock = stockMapper.selectById(saleOrder.getSaleOrderGoodsId() + "," + saleOrder.getSaleOrderRepoId());
            stockMapper.updateById(stock.setStockCount(stock.getStockCount()+saleOrder.getSaleOrderCount()));
            String message = saleOrderMapper.updateById(new SaleOrder().setSaleOrderId(id).setDeleted(DeletedEnum.TRUE).setSaleOrderStatus(2).setUpdatedBy(cur.getUsername()).setUpdatedTime(new Date())) == 1 ? "删除成功" : "删除失败";
            Integer count = saleOrderMapper.selectCount(new QueryWrapper<SaleOrder>().eq("order_group_id", id).eq("deleted", DeletedEnum.FALSE));
            if (count == 0){
                orderGroupMapper.updateById(new OrderGroup().setId(id).setDeleted(DeletedEnum.TRUE));
            }
            return message;
        }
        return "销售订单不存在";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int outStock(String id, LoginUser currentUser) {
        try {
            OrderGroup orderGroup = orderGroupMapper.selectById(id);
            orderGroup.setSaleOrderList(saleOrderMapper.selectList(new QueryWrapper<SaleOrder>().eq("order_group_id",id).eq("deleted",DeletedEnum.FALSE)));
            //排除已入库的和退货的
            if (orderGroup.getSaleOrderList().get(0).getSaleOrderStatus() != 0){
                return -1;
            }
            //拼出id
            List<String> stringList = orderGroup.getSaleOrderList().stream().map(saleOrder ->
                    saleOrder.getSaleOrderGoodsId() +","+ saleOrder.getSaleOrderRepoId()).collect(Collectors.toList());
            QueryWrapper<Stock> qw = new QueryWrapper<Stock>().in("id", stringList);
            List<Stock> stockList = stockMapper.selectList(qw);
            Map<String, SaleOrder> maps = orderGroup.getSaleOrderList().stream()
                    .collect(Collectors.toMap(order->order.getSaleOrderGoodsId()+","+order.getSaleOrderRepoId(), Function.identity()));
            //减库存
            stockList.forEach(stock -> {
                SaleOrder saleOrder = maps.get(stock.getStockGoodsId()+","+stock.getStockRepoId());
                redisUtil.decr(stock.getId(),stock.getStockCount());
                stock.setUpdatedTime(new Date());
                stock.setUpdatedBy(currentUser.getUsername());
                stockMapper.updateById(stock);
                saleOrder.setSaleOrderStatus(1);
                saleOrder.setUpdatedBy(currentUser.getUsername());
                saleOrder.setUpdatedTime(new Date());
                saleOrderMapper.updateById(saleOrder);
            });
            return 0;
        }catch (Exception e){
            return -1;
        }

    }


    private void spellName(OrderGroupSaleVo orderGroup, LoginUser loginUser) {
        List<String> collect = orderGroup.getSaleOrderAddVoList().stream()
                .map(SaleOrderAddVo::getSaleOrderGoodsId).collect(Collectors.toList());
        //查出汽车表的汽车名来
        //将采购订单内的汽车信息查出，并将汽车信息用顿号拼接
        List<CarInfo> carInfos = carInfoMapper.selectList(new QueryWrapper<CarInfo>().in("info_id", collect));
        Map<String, Car> carMap = carMapper.selectBatchIds(carInfos.stream().map(CarInfo::getParentId).distinct().collect(Collectors.toList()))
                .stream()
                .collect(Collectors.toMap(Car::getCarId, Function.identity()));
        String info = carInfos.stream()
                .map(carInfo -> {
                    Car car = carMap.get(carInfo.getParentId());
                    return String.format("汽车品牌：%s-汽车名:%s-汽车颜色:%s-汽车版本:%s",car.getCarBrand(),car.getCarName(),carInfo.getInfoColor(),carInfo.getInfoVersion());
                }).collect(Collectors.joining("、"));
        String parts = sparePartsMapper.selectList(new QueryWrapper<SpareParts>().in("spare_parts_id", collect))
                .stream().map(SpareParts::getSparePartsName).collect(Collectors.joining("、"));
        //拼一个客户的名字
        List<String> users = orderGroup.getSaleOrderAddVoList().stream().map(SaleOrderAddVo::getSaleOrderUserId).collect(Collectors.toList());
        List<SysUser> userList = sysUserMapper.selectList(new QueryWrapper<SysUser>().in("id", users));

        orderGroup.setOrderName(loginUser.getUsername() + "<-->" + userList.stream().map(SysUser::getRealname).collect(Collectors.joining(",")) + "：" + info + " && " + parts);
    }
}
